//
//  ZYConditionLockTest.m
//  OC_Principle
//
//  Created by wangzhipan on 2025/2/16.
//

#import "ZYConditionLockTest.h"
#import <pthread/pthread.h>

@interface ZYConditionLockTest() {
    pthread_mutex_t _condLock;
    pthread_cond_t _cond;
}
@property (nonatomic, strong, nullable) NSMutableArray *list;
@end

@implementation ZYConditionLockTest
- (instancetype)init
{
    if (self = [super init]) {
        [self initCondLock];
        _list = [NSMutableArray array];
    }
    return self;
}

- (void)dealloc
{
    pthread_cond_destroy(&_cond);
    pthread_mutex_destroy(&_cond);
}

- (void)initCondLock
{
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&_condLock, &attr);
    pthread_cond_init(&_cond, NULL);
    
    pthread_mutexattr_destroy(&attr);
}

- (void)setup
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self removeFirst];
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self removeFirst];
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self removeFirst];
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self addToList:@12];
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self addToList:@34];
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self addToList:@56];
    });
}

- (void)removeFirst
{
    pthread_mutex_lock(&_condLock);
    if (self.list.count == 0) {
        //不满足条件，休眠等待signal唤醒
        pthread_cond_wait(&_cond, &_condLock);
    }
    NSLog(@"remove: %@", [self.list lastObject]);
    [self.list removeLastObject];
    pthread_mutex_unlock(&_condLock);
}

- (void)addToList:(nonnull id)obj
{
    pthread_mutex_lock(&_condLock);
    sleep(2);
    NSLog(@"add: %@", obj);
    [self.list addObject:obj];
    
    pthread_cond_signal(&_cond);
    pthread_mutex_unlock(&_condLock);
}
@end
